package org.convallaria.infrastruct.ce.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.time.Duration;

/**
 * 混合缓存配置属性
 * 
 * @author gjh
 * @since 2024-09-25
 */
@Data
@ConfigurationProperties(prefix = "convallaria.cache.hybrid")
public class HybridCacheProperties {

    /**
     * 缓存策略：write-through, write-back
     */
    private String strategy = "write-through";

    /**
     * L1缓存配置
     */
    private L1CacheConfig l1 = new L1CacheConfig();

    /**
     * L2缓存配置
     */
    private L2CacheConfig l2 = new L2CacheConfig();

    /**
     * 缓存预热配置
     */
    private WarmupConfig warmup = new WarmupConfig();

    @Data
    public static class L1CacheConfig {
        /**
         * 最大缓存数量
         */
        private long maximumSize = 1000;

        /**
         * 写入后过期时间
         */
        private Duration expireAfterWrite = Duration.ofMinutes(30);

        /**
         * 访问后过期时间
         */
        private Duration expireAfterAccess = Duration.ofMinutes(10);

        /**
         * 写入后刷新时间
         */
        private Duration refreshAfterWrite = Duration.ofMinutes(5);

        /**
         * 是否启用统计
         */
        private boolean enableStatistics = true;

        /**
         * 是否启用记录
         */
        private boolean enableRecording = false;
    }

    @Data
    public static class L2CacheConfig {
        /**
         * 键前缀
         */
        private String keyPrefix = "convallaria:hybrid:";

        /**
         * 默认过期时间
         */
        private Duration defaultTtl = Duration.ofHours(1);

        /**
         * 是否使用键前缀
         */
        private boolean useKeyPrefix = true;

        /**
         * 是否启用事务支持
         */
        private boolean enableTransactionSupport = false;

        /**
         * 序列化类型
         */
        private String serializationType = "json";
    }

    @Data
    public static class WarmupConfig {
        /**
         * 是否启用预热
         */
        private boolean enabled = false;

        /**
         * 预热线程池大小
         */
        private int threadPoolSize = 5;

        /**
         * 预热超时时间
         */
        private Duration timeout = Duration.ofMinutes(5);

        /**
         * 预热批次大小
         */
        private int batchSize = 100;
    }
}
